#include "particulas.h"


/*------------------------------------------------------------------------------
	Constructor
------------------------------------------------------------------------------*/
CParticulas::CParticulas()
{
	
	m_iParticulasVivas=50;
	m_iNumParticulas=50;
	m_fGlobalX=0;
	m_fGlobalY=0;
	m_fGlobalZ=0;
	m_fRadio=1;
	m_aColor[0]=1.0;//R
	m_aColor[1]=1.0;//G
	m_aColor[2]=1.0;//B
	m_pTextura=NULL;	
	m_eTipo=PART_FUEGO;	
	m_bVivo=TRUE;
	m_fEscala=1;
	m_fAceleracionX=0;
//	m_eProfundidad=Z_DELANTE;
}

/*------------------------------------------------------------------------------
	Destructor
------------------------------------------------------------------------------*/
CParticulas::~CParticulas()
{
}

/*------------------------------------------------------------------------------
	Initializes particle system
------------------------------------------------------------------------------*/
void CParticulas::Iniciar(int iNumParticulas,ETipoParticulas eTipo,float Vida,float Gravedad,float X,float Y,float Z)
{
	int i;
	
	m_fGravedad=Gravedad;		
	m_fVidaInicial=Vida;
	m_fGlobalX=X;
	m_fGlobalY=Y;
	m_fGlobalZ=Z;	
	m_iNumParticulas=iNumParticulas;	
	m_eTipo=eTipo;
	
	if(m_iNumParticulas>MAX_PARTICULAS)
		m_iNumParticulas=MAX_PARTICULAS;
	
	m_iParticulasVivas=iNumParticulas;
		
	i=0;
	while(i<m_iNumParticulas)
	{
		ResetearParticula(i);
		i++;
	}
}

/*------------------------------------------------------------------------------
	Free memory function
------------------------------------------------------------------------------*/
void CParticulas::Liberar()
{
	m_pTextura=NULL;
}

/*------------------------------------------------------------------------------
	Reset a particle to an initial state
------------------------------------------------------------------------------*/
void CParticulas::ResetearParticula(int i)
{
	float v,phi,theta,acelmod;
	
	v = 0.8*frand()+0.2;
	phi = frand()*M_PI;
	theta = 2.0*frand()*M_PI;
    acelmod=50;
	m_aParticulas[i].m_bActiva=TRUE;
	m_aParticulas[i].m_fGravedadAcel=m_fGravedad;
	
	switch(m_eTipo)
	{
		/*--------------------------------------------*/
		case PART_EXPLOSION:
		case PART_AURA:
			
			acelmod=70;
			m_aParticulas[i].m_fVida=m_fVidaInicial;			
			m_aParticulas[i].m_fFade=frand()+0.01;
	
			m_aParticulas[i].m_fR=m_aColor[0];
			m_aParticulas[i].m_fG=m_aColor[1];
			m_aParticulas[i].m_fB=m_aColor[2];

			m_aParticulas[i].m_fX=m_fGlobalX+((v * cos(theta) * sin(phi))/(m_iNumParticulas/5)*m_fRadio);
			m_aParticulas[i].m_fY=m_fGlobalY+((v * cos(phi))/(m_iNumParticulas/5)*m_fRadio);
			m_aParticulas[i].m_fZ=m_fGlobalZ;//+(v * sin(theta) * sin(phi))/(m_iNumParticulas/5);
		
			m_aParticulas[i].m_fXd= (v * cos(theta) * sin(phi))/acelmod;
			m_aParticulas[i].m_fYd= ((v * cos(phi))/acelmod)+(m_fGravedad*frand());
			m_aParticulas[i].m_fZd= 0;//(v * sin(theta) * sin(phi))/acelmod;
			
			m_aParticulas[i].m_fRot= 0;	
		break;		
		
		/*--------------------------------------------*/
		case PART_FUEGO:			
			m_aParticulas[i].m_fVida=m_fVidaInicial;
			m_aParticulas[i].m_fFade=(frand())+0.03;
	
			
			m_aParticulas[i].m_fR=m_aColor[0];			
			m_aParticulas[i].m_fG=m_aColor[1];
			m_aParticulas[i].m_fB=m_aColor[2];

			m_aParticulas[i].m_fX=m_fGlobalX+(((v * cos(theta) * sin(phi))/(acelmod))*m_fRadio);
			m_aParticulas[i].m_fY=m_fGlobalY+(((v * cos(phi))/acelmod)*m_fRadio);
			m_aParticulas[i].m_fZ=m_fGlobalZ;//+(v * sin(theta) * sin(phi))/acelmod;		
		    
			m_aParticulas[i].m_fXd= 0;
			m_aParticulas[i].m_fYd= (m_fGravedad*frand());
			m_aParticulas[i].m_fZd= 0;
			
			m_aParticulas[i].m_fRot= 0;
		break;		
	}
}

/*------------------------------------------------------------------------------
	Draws all particles
------------------------------------------------------------------------------*/
void CParticulas::Dibujar()
{
	if(!m_pTextura)
		return;
		
	glPushMatrix();
	glLoadIdentity();
   	glEnable( GL_BLEND );    
    glBlendFunc( GL_SRC_ALPHA, GL_ONE );

	glDepthFunc (GL_LEQUAL);
	//if(m_eProfundidad==Z_DETRAS)glDepthFunc (GL_LEQUAL);
	//else 						glDepthFunc (GL_ALWAYS);
	
    m_pTextura->Bind();	
	glBegin( GL_TRIANGLES );
	
	for(int i=0;i<m_iNumParticulas;i++)
	{
		if(m_aParticulas[i].m_bActiva)
		{
			DibujarParticula(i);
		}
	}
	glEnd();
	
	glDepthFunc (GL_LESS);
	
	glDisable( GL_BLEND );
	glPopMatrix();
	glColor4f( 1,1,1,1);


}

/*------------------------------------------------------------------------------
	Draws a particle
------------------------------------------------------------------------------*/
void CParticulas::DibujarParticula(int i)
{
	glColor4f( m_aParticulas[i].m_fR,
		       m_aParticulas[i].m_fG,
		       m_aParticulas[i].m_fB,
		       m_aParticulas[i].m_fVida);
	
    
   	glTexCoord2f( 0.0f,  1.0f ); 
   	glVertex3f( (-0.1f*m_fEscala)+m_aParticulas[i].m_fX, (-0.1f*m_fEscala)+m_aParticulas[i].m_fY,m_aParticulas[i].m_fZ);
   	glTexCoord2f( 1.0f,  1.0f ); 
   	glVertex3f(  (0.1f*m_fEscala)+m_aParticulas[i].m_fX, (-0.1f*m_fEscala)+m_aParticulas[i].m_fY,m_aParticulas[i].m_fZ);
   	glTexCoord2f( 1.0f,  0.0f ); 
   	glVertex3f(  (0.1f*m_fEscala)+m_aParticulas[i].m_fX,  (0.1f*m_fEscala)+m_aParticulas[i].m_fY,m_aParticulas[i].m_fZ);
      
    glTexCoord2f( 0.0f,  1.0f ); 
    glVertex3f( (-0.1f*m_fEscala)+m_aParticulas[i].m_fX, (-0.1f*m_fEscala)+m_aParticulas[i].m_fY,m_aParticulas[i].m_fZ);
   	glTexCoord2f( 1.0f,  0.0f ); 
   	glVertex3f(  (0.1f*m_fEscala)+m_aParticulas[i].m_fX,  (0.1f*m_fEscala)+m_aParticulas[i].m_fY,m_aParticulas[i].m_fZ);
    glTexCoord2f( 0.0f,  0.0f ); 
    glVertex3f( (-0.1f*m_fEscala)+m_aParticulas[i].m_fX,  (0.1f*m_fEscala)+m_aParticulas[i].m_fY,m_aParticulas[i].m_fZ);
     
  	m_aParticulas[i].m_fX+=m_aParticulas[i].m_fXd+m_fAceleracionX;
	m_aParticulas[i].m_fY+=m_aParticulas[i].m_fYd;//+m_aParticulas[i].m_fGravedadAcel;
	m_aParticulas[i].m_fZ+=m_aParticulas[i].m_fZd;
   	
	m_aParticulas[i].m_fGravedadAcel+=m_fGravedad;
	
	m_aParticulas[i].m_fVida-=m_aParticulas[i].m_fFade;
	
	if(m_aParticulas[i].m_fVida<=0)
	{		
		switch(m_eTipo)
		{
			case PART_EXPLOSION:
				m_iParticulasVivas--;
				m_aParticulas[i].m_bActiva=FALSE;
				if(m_iParticulasVivas<=0)
					m_bVivo=FALSE;
			break;
			case PART_AURA:
				ResetearParticula(i);
			break;
			case PART_FUEGO:
				ResetearParticula(i);
			break;
		}
	}
}
/*------------------------------------------------------------------------------
	Is particle alive?
------------------------------------------------------------------------------*/
Bool CParticulas::getVivo()
{
	if(m_iParticulasVivas>0 && m_bVivo)
		return TRUE;
	
	return FALSE;
}

